package com.msh.artascope.devcloud.service.thread;

import com.alibaba.fastjson.JSON;
import com.msh.artascope.devcloud.client.enums.biz.JenkinsBuildResultEnum;
import com.msh.artascope.devcloud.client.po.EnvPo;
import com.msh.artascope.devcloud.client.po.JenkinsConfigPo;
import com.msh.artascope.devcloud.client.po.ModuleBuildPo;
import com.msh.artascope.devcloud.client.po.ProjectPo;
import com.msh.artascope.devcloud.client.qo.ModuleBuildQo;
import com.msh.artascope.devcloud.service.service.EnvService;
import com.msh.artascope.devcloud.service.service.JenkinsConfigService;
import com.msh.artascope.devcloud.service.service.ModuleBuildService;
import com.msh.artascope.devcloud.service.service.ProjectService;
import com.msh.artascope.devcloud.service.wrapper.JenkinsWrapper;
import com.msh.frame.client.exception.BizException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

@Slf4j
public class JenkinsBuildResultRunnable implements Runnable{
  private final JenkinsWrapper jenkinsWrapper;
  private final ModuleBuildService moduleBuildService;
  private final ProjectService projectService;
  private final JenkinsConfigService jenkinsConfigService;
  private final EnvService envService;
  private final long expire;

  public JenkinsBuildResultRunnable(JenkinsWrapper jenkinsWrapper, ModuleBuildService moduleBuildService, ProjectService projectService, JenkinsConfigService jenkinsConfigService, EnvService envService) {
    this(jenkinsWrapper, moduleBuildService, projectService, jenkinsConfigService, envService, 20 *60 *1000L);
  }

  public JenkinsBuildResultRunnable(JenkinsWrapper jenkinsWrapper, ModuleBuildService moduleBuildService, ProjectService projectService, JenkinsConfigService jenkinsConfigService, EnvService envService, long expire) {
    this.jenkinsWrapper = jenkinsWrapper;
    this.moduleBuildService = moduleBuildService;
    this.projectService = projectService;
    this.jenkinsConfigService = jenkinsConfigService;
    this.envService = envService;
    this.expire = expire;
  }

  private long maxId;

  @Override
  public void run() {
    while(true){
      try {
        TimeUnit.SECONDS.sleep(5);
        List<ModuleBuildPo> list = moduleBuildService
            .list(new ModuleBuildQo().setResult(JenkinsBuildResultEnum.BUILDING.getDesc()).setIdGt(maxId).setPageSize(10));
        if(CollectionUtils.isEmpty(list)){
          continue;
        }
        maxId = list.get(0).getId()-1;
        list.stream().forEach(build ->{
          long now = System.currentTimeMillis();
          try {
            Long tenantId = build.getTenantId();
            if(now - build.getCreateTime().getTime() > expire){
              updateBuildResult(build.getId(), JenkinsBuildResultEnum.FAIL.getDesc(), tenantId);
            }
            ProjectPo projectPo = projectService.get(build.getProjectId(), tenantId);
            //找不到项目为错误数据
            if(null == projectPo){
              updateBuildResult(build.getId(), JenkinsBuildResultEnum.FAIL.getDesc(), tenantId);
            }
            JenkinsConfigPo jenkinsConfigPo = jenkinsConfigService.getByEnvId(projectPo.getEnvId(), projectPo.getTenantId());
            BizException.doThrowIfNull("缺少jenkins配置", jenkinsConfigPo);
            EnvPo envPo = envService.get(projectPo.getEnvId(), tenantId);
            BizException.doThrowIfNull("无法获取环境信息", envPo);

            JenkinsBuildResultEnum result = jenkinsWrapper.getBuildResult(jenkinsConfigPo, envPo.getNamespace(), projectPo.getName(), build.getBuildNum());
            if(JenkinsBuildResultEnum.SUCCESS.equals(result)){
              updateBuildResult(build.getId(), JenkinsBuildResultEnum.SUCCESS.getDesc(), tenantId);
            }else if(JenkinsBuildResultEnum.FAIL.equals(result)){
              updateBuildResult(build.getId(), JenkinsBuildResultEnum.FAIL.getDesc(), tenantId);
            }
          }catch (Exception e){
            log.warn("查询构建结果异常 {}, ", JSON.toJSONString(build), e);
          }
        });
      } catch (InterruptedException e) {
      } catch (Exception e) {
        log.warn("线程运行出现异常", e);
      }
    }
  }

  private void updateBuildResult(Long buildId, String result, Long tenantId){
    ModuleBuildPo moduleBuildPo = moduleBuildService.get(buildId, tenantId);
    if(null == moduleBuildPo){
      return;
    }
    moduleBuildPo.setResult(result);
    moduleBuildService.update(moduleBuildPo);
  }

}
